package com.access.boot.apisdk;

import com.access.boot.apisdk.executor.HttpRequestExecutor;
import com.access.boot.apisdk.param.resolve.HandlerMethodArgumentResolver;
import com.access.boot.apisdk.param.resolve.argument.HeaderMethodArgumentResolver;
import com.access.boot.apisdk.param.resolve.argument.PathVariableMethodArgumentResolver;
import com.access.boot.apisdk.param.resolve.argument.RequestBodyMethodArgumentResolver;
import com.access.boot.apisdk.param.resolve.argument.RequestParamMethodArgumentResolver;
import com.access.boot.apisdk.util.HandlerMethod;
import com.access.boot.apisdk.util.MethodParameter;
import com.alibaba.fastjson.JSON;
import okhttp3.Request;

import java.lang.reflect.AnnotatedType;
import java.util.Arrays;
import java.util.List;

/**
 * @author Yangzhen
 * @date 2023/1/9 20:38
 * @since 1.0.0
 */
public class RequestResponseResolver {

    private List<HandlerMethodArgumentResolver<RequestContext>> handlerMethodArgumentResolvers =
            Arrays.asList(
                    new PathVariableMethodArgumentResolver(),
                    new HeaderMethodArgumentResolver(),
                    new RequestParamMethodArgumentResolver(),
                    new RequestBodyMethodArgumentResolver()
            );

    private HttpRequestExecutor httpRequestExecutor = new HttpRequestExecutor();

    public <T> T doRequest(HandlerMethod handlerMethod, SdkContext sdkContext, Object... args) {

        RequestContext requestContext = new RequestContext(handlerMethod, sdkContext);
        MethodParameter[] methodParameters = handlerMethod.getMethodParameters();
        for (HandlerMethodArgumentResolver<RequestContext> handlerMethodArgumentResolver : handlerMethodArgumentResolvers) {
            for (MethodParameter methodParameter : methodParameters) {
                if (handlerMethodArgumentResolver.supportsParameter(methodParameter)) {
                    handlerMethodArgumentResolver.resolveArgument(requestContext, methodParameter, args);
                }
            }
        }
        requestContext.addHeader("token", sdkContext.token);
        Request request = requestContext.getRequest();

        try {
            String response = httpRequestExecutor.doExecute(request);
            AnnotatedType returnType = handlerMethod.getReturnType();
            Result result = JSON.parseObject(response, Result.class);
            if (result.getCode() != 0) {
                throw new RuntimeException(result.getMsg());
            }
            Object data = result.getData();
            String s = JSON.toJSONString(data);
            return (T) JSON.parseObject(s, returnType.getType());
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage());
        }
    }
}
